home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / stronged / CHelp_c_riphelp < prev    next >
Encoding:
Text File  |  1993-02-13  |  4.3 KB  |  220 lines

  1. /*
  2.  * riphelp.c
  3.  * Extracts help data from Acorn's !SrcEdit and turns it into a help system
  4.  * for !StrongHlp.
  5.  *
  6.  * Version: 13feb93
  7.  * Copyright (C) Mark H. Wilkinson 1993.
  8.  */
  9.  
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15.  
  16. typedef enum { NO = 0, YES = 1} Boolean;
  17.  
  18.  
  19.  
  20. /*
  21.  * This is where the prepared help pages are stored; these bits of text are
  22.  * not run through fix_text() and so may include link words. Extra pages
  23.  * should be added in separate files and #included to keep this file as
  24.  * short as possible. The title page is last in the list if only to ensure
  25.  * that the last initialiser doesn't have a comma after it (thanks ANSI!).
  26.  */
  27.  
  28. typedef struct {
  29.     char *name;
  30.     Boolean searchable;
  31.     char *text;
  32. } prepared_help_page;
  33.  
  34. static prepared_help_page help[] = {
  35.  
  36. #include "operators.c"
  37.  
  38. "$", NO,
  39. "The C Programming Language\n"
  40. "Help on the C programming language\n"
  41. "\n"
  42. "          <Operators>\n"
  43. "\n"
  44. "Text prepared by Mark H. Wilkinson"
  45.  
  46. };
  47.  
  48.  
  49.  
  50. /*
  51.  * Code to create an in-memory list of help pages. The list is sorted
  52.  * alphabetically by name.
  53.  */
  54.  
  55. typedef struct _index_entry {
  56.     int name_offset;        /* In the index file */
  57.     int text_offset;        /* In the help data file */
  58.     int text_length;
  59.     int flags;
  60. } index_entry;
  61.  
  62. typedef struct _node {
  63.     index_entry index;
  64.     char *name;
  65.     char *text;
  66.     struct _node *next;        /* Yes folks, it's a linked list... */
  67. } node;
  68.  
  69. static int entries;
  70. static node *head;
  71. static FILE *HelpData, *Index;
  72.  
  73. static int cstrcmp(char *s1, char *s2)
  74. {
  75.     int c1, c2;
  76.  
  77.     do
  78.     {
  79.         c1 = *s1++;
  80.         if (isupper(c1)) c1 = tolower(c1);
  81.         c2 = *s2++;
  82.         if (isupper(c2)) c2 = tolower(c2);
  83.     }
  84.     while (c1 && c1 == c2);
  85.         return(c1 - c2);
  86. }
  87.  
  88.  
  89. static void new_entry(char *name, char *text, Boolean searchable)
  90. {
  91.     node *new, **test;
  92.  
  93.     if ((new = malloc(sizeof(node))) != NULL &&
  94.         (new->name = malloc(strlen(name)+1)) != NULL &&
  95.         (new->text = malloc(strlen(text)+1)) != NULL)
  96.     {
  97.         new->index.text_length = strlen(text);
  98.         new->index.flags = searchable ? 0 : 1;
  99.         strcpy(new->name, name);
  100.         strcpy(new->text, text);
  101.         test = &head;
  102.         while (*test != NULL && cstrcmp(new->name, (*test)->name) >= 0)
  103.             test = &((*test)->next);
  104.         new->next = *test;
  105.         *test = new;
  106.         ++entries;
  107.         return;
  108.     }
  109.     fprintf(stderr, "Out of memory.\n");
  110.     exit(EXIT_FAILURE);
  111. }
  112.  
  113.  
  114. static void build_help(void)
  115. {
  116.     node *current;
  117.     int name_offset;
  118.  
  119.     HelpData = fopen("<StrongHelp$Dir>.HelpData.C.HelpData", "wb");
  120.     Index = fopen("<StrongHelp$Dir>.HelpData.C.Index", "wb");
  121.  
  122.     current = head;
  123.     while (current != NULL)
  124.     {
  125.         current->index.text_offset = (int) ftell(HelpData);
  126.         fwrite(current->text, sizeof(char), current->index.text_length, HelpData);
  127.         current = current->next;
  128.     }
  129.  
  130.     fwrite(&entries, sizeof(int), 1, Index);
  131.  
  132.     name_offset = sizeof(int) + entries * sizeof(index_entry);
  133.     current = head;
  134.     while (current != NULL)
  135.     {
  136.         current->index.name_offset = name_offset;
  137.         fwrite(¤t->index, sizeof(index_entry), 1, Index);
  138.         name_offset += strlen(current->name)+1;
  139.         current = current->next;
  140.     }
  141.  
  142.     current = head;
  143.     while (current != NULL)
  144.     {
  145.         fwrite(current->name, sizeof(char), strlen(current->name)+1, Index);
  146.         current = current->next;
  147.     }
  148. }
  149.  
  150.  
  151. /*
  152.  * Put backslashes into a piece of text so that !StrongHlp displays it as
  153.  * normal text with no embedded buttons.
  154.  */
  155. void fix_entry(char *s)
  156. {
  157.     char *f, *t;
  158.     int c = 0;
  159.  
  160.     for (f = s; *f != '\000'; ++f)
  161.         if (*f == '<') ++c;
  162.  
  163.     for (t = f + c; c > 0; --f, --t) {
  164.         *t = *f;
  165.         if (*f == '<') {
  166.             *--t = '\\';
  167.             --c;
  168.         }
  169.     }
  170. }
  171.  
  172.  
  173. static char line[100], name[100], text[5000];    /* Upper limits on text size */
  174. static FILE *Source;
  175.  
  176. int main()
  177. {
  178.     char *eol;
  179.     int i;
  180.  
  181.     Source = fopen("<SrcEdit$Dir>.help.C", "r");
  182.  
  183.     if (Source == NULL)
  184.     {
  185.         fputs("riphelp: Can't open <SrcEdit$Dir>.help.C -\n"
  186.               "         has !SrcEdit been loaded?\n", stderr);
  187.         exit(EXIT_FAILURE);
  188.     }
  189.  
  190.     for (i = 0; i < sizeof(help)/sizeof(help[0]); i++)
  191.         new_entry(help[i].name, help[i].text, help[i].searchable);
  192.  
  193.     while (!feof(Source))
  194.     {
  195.         fgets(line, 100, Source);
  196.         switch (line[0]) {
  197.         case '%' :
  198.             eol = text+strlen(text)-1;
  199.             while (*eol == '\n')
  200.                 *eol-- = '\000';
  201.             if (name[0] != '\000')
  202.             {
  203.                 fix_entry(text);
  204.                 new_entry(name, text, YES);
  205.             }
  206.             eol = strchr(line+1, '\n');
  207.             *eol = '\000';
  208.             strcpy(name, line+1);
  209.             *eol = '\n';
  210.             strcpy(text, line+1);
  211.             break;
  212.         default :
  213.             strcat(text, line);
  214.             break;
  215.         }
  216.     }
  217.  
  218.     build_help();
  219. }
  220.